#include "commom_ipc.h"
#include <unistd.h>
#include <iostream>

using namespace std;

#define KEY 0x87654321
#define AVAIL_VALUE 5
#define MUTEX_VALUE 1
#define FULL_VALUE  0

#define MUTEX_INDEX 0
#define AVAIL_INDEX 1
#define FULL_INDEX  2


int produce(ShareMemoryData *pdata)
{
    /*
    int temp = pdata->start;
    pdata->start = (pdata->start + 1) % AVAIL_VALUE;
    cout<< "produce: "<<temp<<endl;
    */

    return SUCCESS;
}

int consume(ShareMemoryData *pdata)
{
    /*
    int temp = pdata->end;
    pdata->end = (pdata->end + 1) % AVAIL_VALUE;
    cout<< "consume: "<<temp<<endl;
    */

    return SUCCESS;
}

int main()
{
    int i = 0,child = -1;

    Semaphore my_sem(KEY, 3);
    ShareMemory shm(KEY);
    ShareMemoryData shm_data;
    my_sem.InitSem(MUTEX_INDEX,MUTEX_VALUE);
    my_sem.InitSem(AVAIL_INDEX,AVAIL_VALUE);
    my_sem.InitSem(FULL_INDEX,FULL_VALUE);


    for(i = 0; i < 5; i++)
    {
        if((child = fork()) < 0)
        {
            printf("the fork failed");
            exit(1);
        }
        else if(child == 0)
        {
            printf("process[%d],PID = %d\n",i,getpid());
            Semaphore my_sem(KEY, 3);
            ShareMemory shm(KEY);
            ShareMemoryData shm_data;
            while(1)
            {
                my_sem.WaitSem(FULL_INDEX);
                my_sem.WaitSem(MUTEX_INDEX);
                shm.get_shm(&shm_data);
                consume(&shm_data);
                shm.set_shm(&shm_data);
                my_sem.SignalSem(MUTEX_INDEX);
                my_sem.SignalSem(AVAIL_INDEX);
            }
            break;
        }
    }



    if(child > 0)
    {
        while(1)
        {
            my_sem.WaitSem(AVAIL_INDEX);
            my_sem.WaitSem(MUTEX_INDEX);
            shm.get_shm(&shm_data);
            produce(&shm_data);
            shm.set_shm(&shm_data);
            my_sem.SignalSem(MUTEX_INDEX);
            my_sem.SignalSem(FULL_INDEX);
            usleep(10*1000);
        }
    }

    return SUCCESS;
}
